//#include "stdafx.h"
#ifndef QUERYP_GUARD
#define QUERYP_GUARD
#include <vector>
#include <string>
#include <iostream>
#include "QueryProcessor.h"
#include "SPA_Data_Types.h"
using std::vector;
using namespace std;



	struct suchThatClause 
	{
		int index;
		int relationshipType;
		vector<Argument> arguments;

	}; 

	struct withClause
	{
		int index;
		vector<Argument> arguments;
		int withType; 
	};
	struct patternClause
	{
		int index;
		vector<Argument> arguments;
		PAT_Argument stringArgument;

	};
	struct independentNodes
	{
	vector<Argument> arguments;

	};
	enum suchThatType
	{
		FOLLOWS,PARENT,MODIFIES, USES,CALLS, CALLST, NEXT, FOLLOWST, PARENTT, NEXTT, AFFECTS,AFFECTST
	};
enum expressionTypes {
	ot_OPERATOR, ot_VARIABLE, ot_NUMBER, ot_LEFTBRACKET, ot_RIGHTBRACKET, ot_SPACE 
};
class Query_Preprocessor
{
	
private:

	QueryProcessor queryObj;
	vector<string> entityTable;
	vector<vector<string>> entityTableMapping;
	vector<string> RelationshipTable;
	vector<vector<string>> attrName;
	vector<vector<int>> attrNameMapping;
	vector<vector<int>> dependencyList;
	vector<independentNodes> independentList;
	vector<int> NoOfArguments;
	vector<int> arg1Follows;
	vector<int> arg2Follows;
	vector<int> arg1FollowsT;
	vector<int> arg2FollowsT;
	vector<int> arg1Modifies;
	vector<int> arg2Modifies;
	vector<int> arg1Uses;
	vector<int> arg2Uses;
	vector<int> arg1Parent;
	vector<int> arg2Parent;
	vector<int> arg1ParentT;
	vector<int> arg2ParentT;
	vector<int> arg1Call;
	vector<int> arg2Call;
	vector<int> arg1CallT;
	vector<int> arg2CallT;
	vector<int> arg1Next;
	vector<int> arg2Next;
	vector<int> arg1NextT;
	vector<int> arg2NextT;
	vector<int> arg1Affects;
	vector<int> arg2Affects;
	vector<int> arg1AffectsT;
	vector<int> arg2AffectsT;
		


public:
	Query_Preprocessor();
	void createEntityTable();
	void createEntityRelTable();
	void createMapping(int,vector<string>& variable,struct Result& result,struct Result& resulIndependent);
	int getEntityIndex(string,int&,int&);
	int getRelationshipIndex(string);
	bool checkRelationshipArgumentsValidity(int,int,int);
	int createQueryTree(string,vector<suchThatClause>& suchThat,struct Result& result,vector<withClause>& with,vector<patternClause>& pattern); 
	int isNumber(string);
	int checkAttributeCompatibility(Argument &argument1,Argument &arg2);
	int checkAttributeName(int,string);
	int tokenize(vector<string>& token,const string& str,const string& delimiters);
	int checkIntArgument(int argument,int argType);
	int checkIndependence(vector<QRYSTATEMENT_TYPE> &resultType, Argument &argument1,Argument &argument2);
	int validateExpression(string &expression);
	void updateDependencyList(Argument &dependencyArg);
};
#endif